package com.azt.front.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.FastJsonJsonView;
import com.azt.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Exception 统一处理，取代 @ExceptionHandler
 * Created by LiQZ on 2017/3/14.
 */
public class ExceptionInterceptor implements HandlerExceptionResolver {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Override
	public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception exception) {
		if (exception == null) {
			return new ModelAndView();
		}
		// spring bind exception
		if (exception instanceof BindException) {
            BindingResult bindingResult = ((BindException) exception).getBindingResult();
			ModelAndView mv = getErrorJsonView(400, getFirstErrorMsg(bindingResult), getErrorMsg(bindingResult));
			return mv;
		}
        // 服务层抛出异常
		if (exception instanceof ServiceException) {
			ModelAndView mv = getErrorJsonView(((ServiceException) exception).getCode(), exception.getMessage(), null);
			return mv;
		}
		// 其他异常不处理
		return null;
	}

	/**
	 * 使用FastJson提供的FastJsonJsonView视图返回，不需要捕获异常
	 */
	public static ModelAndView getErrorJsonView(int code, String message, Object data) {
		ModelAndView modelAndView = new ModelAndView();
		FastJsonJsonView jsonView = new FastJsonJsonView();
		Map<String, Object> errorInfoMap = new HashMap<>();
		errorInfoMap.put("code", code);
		errorInfoMap.put("message", message);
		errorInfoMap.put("data", data);
		jsonView.setAttributesMap(errorInfoMap);
		modelAndView.setView(jsonView);
		return modelAndView;
	}

    private static String getFirstErrorMsg(BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            List<FieldError> objectErrorList= bindingResult.getFieldErrors();
            for (FieldError objectError : objectErrorList) {
                return objectError.getDefaultMessage();
            }
        }
        return null;
    }

	/**
	 * 获取错误列表
	 */
	private static JSONObject getErrorMsg(BindingResult bindingResult) {
        JSONObject jsonError = new JSONObject();
		if (bindingResult.hasErrors()) {
			List<FieldError> objectErrorList= bindingResult.getFieldErrors();
			for (FieldError objectError : objectErrorList) {
                jsonError.put(objectError.getField(), objectError.getDefaultMessage());
			}
		}
		return jsonError;
	}

}
